import pandas as pd
import os
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font, Border, Side

# ========== 可配置参数 ==========
# Excel文件路径 (请确保路径正确)
EXCEL_FILE_PATH = r'C:\Users\赛福工程部\Desktop\挤压拉值机数据确认点表-20250210.xlsx'

# 要处理的工作表列表
SHEET_NAMES = ['总表', '挤压', '在线淬火', '牵引机', '拉直', '锯切']

# 要提取的列名
COLUMNS_TO_EXTRACT = [
    '工序',
    '采样设备名称/型号',
    '采样参数名称',
    'PLC点位/数据类型',
    '采样点个数',
    '设备IP地址',
    '数采频次',
    '数据类型',
    '备注',
]

# 表头搜索的最大行数
MAX_HEADER_SEARCH_ROWS = 30

# 输出文件路径
OUTPUT_DIR = os.path.join(os.getcwd(), 'output')
OUTPUT_FILE_PATH = os.path.join(OUTPUT_DIR, '挤压拉值机数据确认点表_合并.xlsx')


# ========== 核心功能函数 ==========
def copy_font(source_font):
    """复制字体样式属性"""
    if not source_font:
        return Font()
    return Font(
        name=source_font.name,
        size=source_font.size,
        bold=source_font.bold,
        italic=source_font.italic,
        vertAlign=source_font.vertAlign,
        underline=source_font.underline,
        strike=source_font.strike,
        color=source_font.color.rgb if source_font.color else None
    )


def extract_data_from_sheet(df_original, sheet_name, columns_to_extract):
    df = df_original.copy()
    extracted_data = []
    header_style = None

    # 移除多表查询逻辑，直接处理整个工作表
    # 使用列索引而非表头名称提取数据
    num_columns = len(columns_to_extract)
    if len(df.columns) < num_columns:
        print(f"  ✗ 工作表'{sheet_name}'列数不足，无法提取数据")
        return None

    # 直接使用列索引提取数据（假设数据按固定顺序排列）
    df_data = df.iloc[:, :num_columns].copy()
    df_data.columns = columns_to_extract

    # 过滤空行
    df_data = df_data.dropna(how='all').reset_index(drop=True)

    if not df_data.empty:
        print(f"  ✓ 从 '{sheet_name}' 提取了 {len(df_data)} 条记录")
        return {
            'data': df_data,
            'sheet_name': sheet_name,
            'header_style': header_style
        }
    print(f"  ✗ '{sheet_name}' 未提取到任何有效数据")
    return None


def add_table_border(worksheet, start_row, end_row, start_col, end_col):
    """为指定区域添加内外表格线"""
    if start_row > end_row or start_col > end_col:
        return

    thin_border = Border(left=Side(style='thin'),
                         right=Side(style='thin'),
                         top=Side(style='thin'),
                         bottom=Side(style='thin'))

    for row in worksheet.iter_rows(min_row=start_row, max_row=end_row, min_col=start_col, max_col=end_col):
        for cell in row:
            cell.border = thin_border


# ========== 主程序 ==========
# 删除find_header_row函数，因为不再需要表头识别

# 在主程序中，修改工作表处理部分
if __name__ == "__main__":
    print(f"开始处理文件: {EXCEL_FILE_PATH}")

    try:
        # 使用data_only=True读取单元格值而非公式
        wb = load_workbook(EXCEL_FILE_PATH, data_only=True)
        excel_file = pd.ExcelFile(EXCEL_FILE_PATH)
    except FileNotFoundError:
        print(f"错误：文件未找到，请检查路径 -> {EXCEL_FILE_PATH}")
        exit(1)
    except Exception as e:
        print(f"打开文件失败: {e}")
        exit(1)

    all_sheets_data = []
    for sheet_name in SHEET_NAMES:
        print(f"\n处理工作表: '{sheet_name}'...")
        if sheet_name not in excel_file.sheet_names:
            print(f"  ✗ 工作表不存在")
            continue
        # 直接读取所有数据，不指定表头
        df = excel_file.parse(sheet_name, header=None)

        sheet_data = extract_data_from_sheet(df, sheet_name, COLUMNS_TO_EXTRACT)
        if sheet_data:
            all_sheets_data.append(sheet_data)

    if not all_sheets_data:
        print("\n未提取到任何数据，程序结束。")
        exit(0)

    # 创建或清空用于输出的工作表
    if '合并数据' in wb.sheetnames:
        wb.remove(wb['合并数据'])
    output_ws = wb.create_sheet('合并数据', 0)

    current_row = 1
    # 遍历所有提取到的数据块并写入新的Excel文件
    for i, sheet_info in enumerate(all_sheets_data):
        df_to_write = sheet_info['data']
        sheet_name_title = sheet_info['sheet_name']

        # 写入每个来源工作表的标题
        title_cell = output_ws.cell(row=current_row, column=1, value=f"来源工作表: {sheet_name_title}")
        title_cell.font = Font(bold=True, size=14)
        current_row += 2  # 标题和表格之间空一行

        table_start_row = current_row

        # 写入表头
        for col_idx, col_name in enumerate(df_to_write.columns, 1):
            cell = output_ws.cell(row=current_row, column=col_idx, value=col_name)
            cell.font = Font(bold=True)
        current_row += 1

        # 写入数据行
        for _, data_row in df_to_write.iterrows():
            for col_idx, col_name in enumerate(df_to_write.columns, 1):
                cell_value = data_row.get(col_name)
                # 将Pandas的空值(NaT, NaN)转换为空字符串
                if pd.isna(cell_value):
                    cell_value = ""
                output_ws.cell(row=current_row, column=col_idx, value=cell_value)
            current_row += 1

        table_end_row = current_row - 1
        # 添加边框
        add_table_border(output_ws, table_start_row, table_end_row, 1, len(df_to_write.columns))
        current_row += 2  # 每个表格之间空两行

    # 自动调整列宽
    for column_cells in output_ws.columns:
        # 中文环境下，宽度需要乘以更大的系数
        max_length = 0
        column_letter = get_column_letter(column_cells[0].column)
        for cell in column_cells:
            try:
                # 计算字符长度，一个中文字符约等于2个英文字符宽
                cell_len = sum(2 if '\u4e00' <= char <= '\u9fff' else 1 for char in str(cell.value))
                if cell_len > max_length:
                    max_length = cell_len
            except:
                pass
        # 设置一个合理的宽度，并设置最大宽度上限
        adjusted_width = max_length + 4
        output_ws.column_dimensions[column_letter].width = min(adjusted_width, 60)

    # 创建输出目录并保存文件
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    try:
        wb.save(OUTPUT_FILE_PATH)
        print(f"\n✓ 导出成功! 文件保存在: {OUTPUT_FILE_PATH}")
    except PermissionError:
        print(f"\n✗ 导出失败：权限错误。请关闭正在打开的Excel文件 '{os.path.basename(OUTPUT_FILE_PATH)}' 后重试。")
    except Exception as e:
        print(f"\n✗ 导出失败: {e}")
